﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using HA.ModFlow.Domain.DomainLayer;


namespace HA.Data
{
    [Serializable]
    public class BCRiver:BCType,ICloneable
    {

        public BCRiver():base()
        {

            this._isPtType = true;

            this._isLnType = true;

            this._isPyType = true;




            //this._multiConductance = new List<double>();



            //this._multiElevation = new List<double>();


            //this._multiStage = new List<double>();



            //this._multiEndStage = new List<double>();


            //this._multiStartStage = new List<double>();


            //this._multiendElevation = new List<double>();



            //this._multistartElevation = new List<double>();


            //for (int i = 0; i < this.NPeriods; i++)
            //{
            //    this._multiConductance.Add(0);
            //    this._multiElevation.Add(0);
            //    this._multiendElevation.Add(0);
            //    this._multiEndStage.Add(0);
            //    this._multiStage.Add(0);
            //    this._multistartElevation.Add(0);
            //    this._multiStartStage.Add(0);
            //}

        }


        //double _conductance;


        /// <summary>
        /// 在点模式下，这个标识实际的传导率 ，在线模式下，表示每一段距离的传导率，，在面模式下表示单位面积的传导率
        /// </summary>
        public double Conductance
        {
            get { return this._multiConductance.IsDataConst ? _multiConductance.ConstData : this._multiConductance.BCDatas[0].Value; }
            set
            {
                if (this._multiConductance.IsDataConst)
                    this._multiConductance.ConstData = value;
                else
                    this._multiConductance.BCDatas[0].Value = value;
            }
        }


        BCDateDataCollection _multiConductance = new BCDateDataCollection();

        public BCDateDataCollection MultiConductance
        {
            get { return _multiConductance; }
            set { _multiConductance = value; }
        }

        //double _stage;

        public double Stage
        {
            get { return this._multiStage.IsDataConst ? _multiStage.ConstData : this._multiStage.BCDatas[0].Value; }
            set
            {
                if (this._multiStage.IsDataConst)
                    this._multiStage.ConstData = value;
                else
                    this._multiStage.BCDatas[0].Value = value;
            }
        }
      

        //double _endStage;
        BCDateDataCollection _multiEndStage = new BCDateDataCollection();

        public double EndStage
        {
            get { return this._multiEndStage.IsDataConst ? _multiEndStage.ConstData : this._multiEndStage.BCDatas[0].Value; }
            set
            {
                if (this._multiEndStage.IsDataConst)
                    this._multiEndStage.ConstData = value;
                else
                    this._multiEndStage.BCDatas[0].Value = value;
            }
        }
        public BCDateDataCollection MultiEndStage
        {
            get { return this._multiEndStage;}
            set { _multiEndStage = value; }
        }

        //double _startStage;
        BCDateDataCollection _multiStartStage = new BCDateDataCollection();

        public double StartStage
        {
            get { return this._multiStartStage.IsDataConst ? _multiStartStage.ConstData : this._multiStartStage.BCDatas[0].Value; }
            set
            {
                if (this._multiStartStage.IsDataConst)
                    this._multiStartStage.ConstData = value;
                else
                    this._multiStartStage.BCDatas[0].Value = value;
            }
        }
        public BCDateDataCollection MultiStartStage
        {
            get { return this._multiStartStage; }
            set { _multiStartStage = value; }
        }



        BCDateDataCollection _multiStage = new BCDateDataCollection();

        public BCDateDataCollection MultiStage
        {
            get { return _multiStage; }
            set { _multiStage = value; }
        }

        //double _elevation;

        public double Elevation
        {
            get { return this._multiElevation.IsDataConst ? _multiElevation.ConstData : this._multiElevation.BCDatas[0].Value; }
            set
            {
                if (this._multiElevation.IsDataConst)
                    this._multiElevation.ConstData = value;
                else
                    this._multiElevation.BCDatas[0].Value = value;
            }
        }

        //double _endElevation;
        BCDateDataCollection _multiendElevation = new BCDateDataCollection();

        public double EndElevation
        {
            get { return this._multiendElevation.IsDataConst ? _multiendElevation.ConstData : this._multiendElevation.BCDatas[0].Value; }
            set
            {
                if (this._multiendElevation.IsDataConst)
                    this._multiendElevation.ConstData = value;
                else
                    this._multiendElevation.BCDatas[0].Value = value;
            }
        }
        public BCDateDataCollection MultiendElevation
        {
            get { return _multiendElevation; }
            set { _multiendElevation = value; }
        }

        //double _startElevation;
        BCDateDataCollection _multistartElevation = new BCDateDataCollection();

        public double StartElevation
        {
            get { return this._multistartElevation.IsDataConst ? _multistartElevation.ConstData : this._multistartElevation.BCDatas[0].Value; }
            set
            {
                if (this._multistartElevation.IsDataConst)
                    this._multistartElevation.ConstData = value;
                else
                    this._multistartElevation.BCDatas[0].Value = value;
            }
        }

        public BCDateDataCollection MultiStratElevation
        {
            get { return _multistartElevation; }
            set { _multistartElevation = value; }
        }


        BCDateDataCollection _multiElevation = new BCDateDataCollection();

        public BCDateDataCollection MultiElevation
        {
            get { return _multiElevation; }
            set { _multiElevation = value; }
        }


        //public override void OnNPeriodsChanged()
        //{
        //    base.OnNPeriodsChanged();

        //    //取得之前数据的个数
        //    int n = this.MultiConductance.Count;



        //    //开始更新数据


        //    if (n < this.NPeriods)
        //    {
        //        int nSub = this.NPeriods - n;

        //        for (int i = 0; i < nSub; i++)
        //        {
        //            this.MultiConductance.Add(0);
        //            this.MultiElevation.Add(0);
        //            this.MultiendElevation.Add(0);
        //            this.MultiEndStage.Add(0);
        //            this.MultiStage.Add(0);
        //            this.MultiStartStage.Add(0);
        //            this.MultiStratElevation.Add(0);
        //        }
        //    }

        //    else
        //    {
        //        int nSub = n - this.NPeriods;
        //        this.MultiConductance.RemoveRange(this.NPeriods, nSub);
        //        this.MultiElevation.RemoveRange(this.NPeriods, nSub);
        //        this.MultiendElevation.RemoveRange(this.NPeriods, nSub);
        //        this.MultiEndStage.RemoveRange(this.NPeriods, nSub);
        //        this.MultiStage.RemoveRange(this.NPeriods, nSub);
        //        this.MultiStartStage.RemoveRange(this.NPeriods, nSub);
        //        this.MultiStratElevation.RemoveRange(this.NPeriods, nSub);
        //    }


        //    //this.NPeriods;

        //}


        public object Clone()
        {

            //throw new NotImplementedException();
            //return this.MemberwiseClone();
            BCRiver bcr = (BCRiver)this.MemberwiseClone();

            bcr._multiConductance = (BCDateDataCollection)this._multiConductance.Clone();


            bcr._multiElevation = (BCDateDataCollection)this._multiElevation.Clone();


            bcr._multiendElevation = (BCDateDataCollection)this._multiendElevation.Clone();


            bcr._multiEndStage = (BCDateDataCollection)this._multiEndStage.Clone();


            bcr._multiStage = (BCDateDataCollection)this._multiStage.Clone();

            bcr._multistartElevation = (BCDateDataCollection)this._multistartElevation.Clone();

            bcr._multiStartStage = (BCDateDataCollection)this._multiStartStage.Clone();

            return bcr;
        }

        public override void MapToModflow(List<double> stressPeriods, List<ValueResult> ijkList, ModFlow.Domain.DomainLayer.ModFlowData mf, FeatureObject owner)
        {
            if (ijkList.Count <= 0) return;
            int k = ijkList[0].K;

            List<int> indice=new List<int>();

            List<River> rivers=new List<River> ();


           double TotalValue= owner.GetTotalLValue();

           //double currentLength=0;

            foreach (ValueResult  item in ijkList)
            {
                //if (item.K != k)
                //{
                //    k = item.K;
                //    currentLength = 0;
                //}
               indice.Add ( mf.GridData.GetIndex(item.I  ,item.J ,item.K ));

               River river = new River(item.I, item.J, item.K, mf.GridData.RowsCount, mf.GridData.ColsCount, mf.GridData.LayersCount, mf.StressPeriods.InnerList.Count);


               if (owner is PointFO)
               {
                   this.assistMapToModFlow(stressPeriods, river.Conductance, _multiConductance);
                   this.assistMapToModFlow(stressPeriods, river.Stage, _multiStage);
                   this.assistMapToModFlow(stressPeriods, river.Elevation, _multiElevation);
                   //river.FirstConductance = this.Conductance;
                   //river.FirstStage = this.Stage;
                   //river.FirstElevation = this.Elevation;
                   
                   //for (int i = 0; i < this.NPeriods; i++)
                   //{
                   //    river.Conductance[i] = this._multiConductance[i];
                   //    river.Stage[i]=this._multiStage[i];
                   //    river.Elevation[i]=this._multiElevation[i];
                   //}
                   
               }

               if (owner is LineFO)
               {
                   List<double> startStage = new List<double>(stressPeriods.Count);
                   List<double> endStage = new List<double>(stressPeriods.Count);
                   List<double> startElevation = new List<double>(stressPeriods.Count);
                   List<double> endElevation = new List<double>(stressPeriods.Count);

                   foreach (var sp in stressPeriods)
                   {
                       startStage.Add(0);
                       endStage.Add(0);
                       startElevation.Add(0);
                       endElevation.Add(0);
                   }

                   this.assistMapToModFlow(stressPeriods, river.Conductance, _multiConductance);
                   this.assistMapToModFlow(stressPeriods, river.Stage, _multiStage);
                   this.assistMapToModFlow(stressPeriods, river.Elevation, _multiElevation);
                   this.assistMapToModFlow(stressPeriods, startStage, _multiStartStage);
                   this.assistMapToModFlow(stressPeriods, endStage, _multiEndStage);
                   this.assistMapToModFlow(stressPeriods, startElevation, _multistartElevation);
                   this.assistMapToModFlow(stressPeriods, endElevation, _multiendElevation);

                   for (int i = 0; i < stressPeriods.Count; i++)
                   {
                       river.Conductance[i] *= item.Value;

                       river.Stage[i] = startStage[i] + (endStage[i] - startStage[i]) * (item.LineCurrentTotalLength / TotalValue);
                       river.Elevation[i] = startElevation[i] + (endElevation[i] - startElevation[i]) * (item.LineCurrentTotalLength / TotalValue);
                       
                   }


                   //for (int i = 0; i < this.NPeriods; i++)
                   //{
                   //    river.Conductance[i] = this._multiConductance[i] * item.Value;

                   //    river.Stage[i] = this._multiStartStage[i] + (this._multiEndStage[i] - this._multiStartStage[i]) * (item.LineCurrentTotalLength / TotalValue);
                   //    river.Elevation[i] = this._multistartElevation[i] + (this._multiendElevation[i] - this._multistartElevation[i]) * (item.LineCurrentTotalLength / TotalValue);
                   
                   //}
                   //currentLength += item.Value;
               
               }



               if (owner is PolygonFO)
               {
                   this.assistMapToModFlow(stressPeriods, river.Conductance, _multiConductance);
                   this.assistMapToModFlow(stressPeriods, river.Stage, _multiStage);
                   this.assistMapToModFlow(stressPeriods, river.Elevation, _multiElevation);

                   for (int i = 0; i < stressPeriods.Count; i++)
                   {
                       river.Conductance[i] *= item.Value;
                   }


                   //for (int i = 0; i < this.NPeriods; i++)
                   //{
                   //    river.Conductance[i] = this._multiConductance[i] * item.Value;

                   //    river.Stage[i] = this._multiStage[i];

                   //    river.Elevation[i] = this._multiElevation[i];
                   //}
                   
               }
             


                rivers.Add (river);
                
            }

              

            //mf.SourceSinks.Rivers.UpdateRivers(rivers,indice);
            mf.SourceSinks.Rivers.AddTempRivers(rivers);


            
        }
    }
}
